package com.cdu.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * projectName : easy-help-v2
 * className: AsyncConfig
 * description: 异步线程调用的基本配置。
 *
 * @author : chengjiang@asiainfo.com
 * @date: 2022/05/11
 */

@Configuration
@Slf4j
public class AsyncConfig implements AsyncConfigurer {

    @Value("${com.cdu.async.corePoolSize}")
    private int corePoolSize = 5;

    @Value("${com.cdu.async.maxPoolSize}")
    private int maxPoolSize = 20;

    @Value("${com.cdu.async.queueCapacity}")
    private int queueCapacity = 10;

    @Value("${com.cdu.async.keepAliveSeconds}")
    private int keepAliveSeconds = 100;

    @Value("${com.cdu.async.threadNamePrefix}")
    private String threadNamePrefix = "async-executor-";

    /**
     * @description : 相关配置的导入，通过yml配置获取相应的数据。
     * @param
     * @return : java.util.concurrent.Executor
     * @author : git.jas0nch
     * date : 2022/5/11
     **/
    @Override
    public Executor getAsyncExecutor() {
        var executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(keepAliveSeconds);
        executor.setThreadNamePrefix(threadNamePrefix);
        // default:
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 拒绝策略；

        executor.initialize();
        return executor;
    }

    /**
     * @description : 异常处理
     * @param
     * @return : org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler
     * @author : git.jas0nch
     * date : 2022/5/11
     **/
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        // lambda
        return (ex, method, params) -> {
            log.error("error msg: {}, error: {}", ex.getMessage(), ex);
            log.error("exception method: {} params: {}", method, params);
        };
    }
}
